import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Company } from "src/modules/company/company.entity";
import { Repository } from "typeorm";
import { CompanyService } from "../company/company.service";
import { Statistic } from "./statistic.entity";
import { Cron } from "@nestjs/schedule";

@Injectable()
export class StatisticService {
  constructor(
    @InjectRepository(Statistic)
    private readonly statisticRepository: Repository<Statistic>,
    private readonly companyService: CompanyService
  ) {}

  async find(id: string) {
    return await this.statisticRepository.findOneOrFail(id);
  }
  async findAll() {
    return await this.statisticRepository.findAndCount();
  }
  findOneWithCompany(id: string): Promise<Statistic> {
    return this.statisticRepository.findOneOrFail(id, {
      relations: ["company"],
    });
  }

  /** 创建一个空的 */
  async create(company: Company | string) {
    company =
      company instanceof Company
        ? company
        : await this.companyService.find(company);
    const today = this.getToday();
    let statistic = await this.statisticRepository.findOne({
      date: today,
      company,
    });
    if (!statistic) {
      statistic = new Statistic();
      statistic.date = today;
      statistic.company = company;
    }
    return statistic;
  }

  @Cron("0 0 0 * * *")
  async initToday() {
    const companies = (await this.companyService.findAll())[0];
    return Promise.all(companies.map((item) => this.create(item)));
  }

  /**
   * @param date { Date.ISOString }
   * @param company { Company }
   */
  async findByDate(date: Date, company: Company | string) {
    company =
      company instanceof Company
        ? company
        : await this.companyService.find(company);
    date = new Date(date.toLocaleDateString());
    return await this.statisticRepository.findOneOrFail({ date, company });
  }

  async findYesterday(company: Company | string) {
    const date = new Date();
    date.setTime(date.getTime() - 24 * 60 * 60 * 1000);
    return this.findByDate(date, company);
  }

  async findToday(company: Company | string) {
    return this.findByDate(new Date(), company);
  }

  async todayOrder(company: Company): Promise<number> {
    return (
      (
        await this.statisticRepository.findOne({
          date: this.getToday(),
          company,
        })
      )?.order ?? 0
    );
  }

  async todayDelivery(company: Company) {
    return (
      (
        await this.statisticRepository.findOne({
          company,
          date: this.getToday(),
        })
      )?.delivery ?? 0
    );
  }

  async appendOrder(company: Company, num = 1) {
    const today = this.getToday();
    let statistic = await this.statisticRepository.findOne({
      date: today,
      company,
    });
    if (statistic) {
      statistic.order += num;
    } else {
      statistic = new Statistic();
      statistic.order = num;
      statistic.company = company;
    }
    return await this.statisticRepository.save(statistic);
  }

  async appendDelivery(company: Company, num = 1) {
    const today = this.getToday();
    let statistic = await this.statisticRepository.findOne({
      date: today,
      company,
    });
    if (statistic) {
      statistic.delivery += num;
    } else {
      statistic = new Statistic();
      statistic.delivery = num;
      statistic.company = company;
    }
    return await this.statisticRepository.save(statistic);
  }

  async remove(statistic: string | Statistic) {
    const id = statistic instanceof Statistic ? statistic.id : statistic;
    const statisticToRemove = await this.statisticRepository.findOneOrFail(id);
    return await this.statisticRepository.remove(statisticToRemove);
  }

  private getToday(): Date {
    return new Date(new Date().toLocaleDateString());
  }
}
